package com.skyolder.milkbee.web.rest;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.codahale.metrics.annotation.Timed;
import com.skyolder.milkbee.domain.Leaguer;
import com.skyolder.milkbee.domain.Message;
import com.skyolder.milkbee.domain.User;
import com.skyolder.milkbee.dto.MyMessage;
import com.skyolder.milkbee.security.SecurityUtils;
import com.skyolder.milkbee.service.LeaguerService;
import com.skyolder.milkbee.service.MessageService;
import com.skyolder.milkbee.service.UserService;
import com.skyolder.milkbee.tool.StringUtil;
import com.skyolder.milkbee.web.rest.util.HeaderUtil;
import com.skyolder.milkbee.web.rest.util.PaginationUtil;

import io.swagger.annotations.ApiParam;

/**
 * REST controller for managing Message.
 */
@RestController
@RequestMapping("/api")
public class MessageResource {

	private final Logger log = LoggerFactory.getLogger(MessageResource.class);

	@Inject
	private MessageService messageService;
	@Inject
	private UserService userService;
	@Inject
	private LeaguerService leaguerService;

	/**
	 * POST /messages : Create a new message.
	 *
	 * @param message
	 *            the message to create
	 * @return the ResponseEntity with status 201 (Created) and with body the
	 *         new message, or with status 400 (Bad Request) if the message has
	 *         already an ID
	 * @throws URISyntaxException
	 *             if the Location URI syntax is incorrect
	 */
	@PostMapping("/messages")
	@Timed
	public ResponseEntity<Message> createMessage(@RequestBody Message message) throws URISyntaxException {
		log.debug("REST request to save Message : {}", message);
		if (message.getId() != null) {
			return ResponseEntity.badRequest().headers(
					HeaderUtil.createFailureAlert("message", "idexists", "A new message cannot already have an ID"))
					.body(null);
		}
		Message result = messageService.save(message);
		return ResponseEntity.created(new URI("/api/messages/" + result.getId()))
				.headers(HeaderUtil.createEntityCreationAlert("message", result.getId().toString())).body(result);
	}

	/**
	 * PUT /messages : Updates an existing message.
	 *
	 * @param message
	 *            the message to update
	 * @return the ResponseEntity with status 200 (OK) and with body the updated
	 *         message, or with status 400 (Bad Request) if the message is not
	 *         valid, or with status 500 (Internal Server Error) if the message
	 *         couldnt be updated
	 * @throws URISyntaxException
	 *             if the Location URI syntax is incorrect
	 */
	@PutMapping("/messages")
	@Timed
	public ResponseEntity<Message> updateMessage(@RequestBody Message message) throws URISyntaxException {
		log.debug("REST request to update Message : {}", message);
		if (message.getId() == null) {
			return createMessage(message);
		}
		Message result = messageService.save(message);
		return ResponseEntity.ok().headers(HeaderUtil.createEntityUpdateAlert("message", message.getId().toString()))
				.body(result);
	}

	/**
	 * GET /messages : get all the messages.
	 *
	 * @param pageable
	 *            the pagination information
	 * @return the ResponseEntity with status 200 (OK) and the list of messages
	 *         in body
	 * @throws URISyntaxException
	 *             if there is an error to generate the pagination HTTP headers
	 */
	@GetMapping("/messages")
	@Timed
	public ResponseEntity<List<Message>> getAllMessages(@ApiParam Pageable pageable) throws URISyntaxException {
		log.debug("REST request to get a page of Messages");
		Page<Message> page = messageService.findAll(pageable);
		HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/messages");
		return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
	}

	/**
	 * GET /messages/:id : get the "id" message.
	 *
	 * @param id
	 *            the id of the message to retrieve
	 * @return the ResponseEntity with status 200 (OK) and with body the
	 *         message, or with status 404 (Not Found)
	 */
	@GetMapping("/messages/{id}")
	@Timed
	public ResponseEntity<Message> getMessage(@PathVariable Long id) {
		log.debug("REST request to get Message : {}", id);
		Message message = messageService.findOne(id);
		return Optional.ofNullable(message).map(result -> new ResponseEntity<>(result, HttpStatus.OK))
				.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
	}

	/**
	 * DELETE /messages/:id : delete the "id" message.
	 *
	 * @param id
	 *            the id of the message to delete
	 * @return the ResponseEntity with status 200 (OK)
	 */
	@DeleteMapping("/messages/{id}")
	@Timed
	public ResponseEntity<Void> deleteMessage(@PathVariable Long id) {
		log.debug("REST request to delete Message : {}", id);
		messageService.delete(id);
		return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert("message", id.toString())).build();
	}

	@GetMapping("/mymessages")
	@Timed
	public ResponseEntity<List<MyMessage>> getMyMessages(@ApiParam Pageable pageable) throws URISyntaxException {
		Optional<User> ouser = userService.getUserWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin());
		User user = ouser.get();
		Long uid = 0L;
		uid = user.getId();
		Page<MyMessage> page = messageService.doQueryMyMessages(uid, pageable);
		for(MyMessage item:page.getContent()){
			if(item.getFromUserId()==uid){
				item.setMe(true);
			}
		}
		HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/mymessages");
		return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
	}
	
	@GetMapping("/mymessage/send")
	@Timed
	public ResponseEntity<MyMessage> sendMyMessage(@ApiParam String content) {
		Optional<User> ouser = userService.getUserWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin());
		User user = ouser.get();
		Long uid = user.getId();
		if(StringUtil.isBlank(content)){
			return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("message", "no reciever",
					"content not has receiver ,please use @receiver")).body(null);
		}
		String[] strings=content.split(" ");
		if(strings.length<2){
			return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("message", "bad format",
					"bad format,right format is: @receiver hello!")).body(null);
		}
		String rcv=strings[0];
		if(!rcv.startsWith("@")){
			return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("message", "bad format",
					"bad format,right format is: @receiver hello!")).body(null);
		}
		rcv=rcv.substring(1);
		Optional<User> orecver  =userService.getUserWithAuthoritiesByLogin(rcv);
		if(!orecver.isPresent()){
			return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("message", "no exists",
					rcv+" is not a valid user!")).body(null);	
		}
		Leaguer fleaguer=leaguerService.findByUser(user);
		User rcver=orecver.get();
		Leaguer tleaguer=leaguerService.findByUser(rcver);
		Message message=new Message();
		message.setContent(content.substring(content.indexOf(" ")));
		message.setCreatedAt(ZonedDateTime.now());
		message.setFromLeaguerId(fleaguer.getId());
		message.setFromUserId(user.getId());
		message.setToLeaguerId(tleaguer.getId());
		message.setToUserId(rcver.getId());
		message=messageService.save(message);
		MyMessage myMessage=new MyMessage(message.getId(), user.getLogin(), rcver.getLogin(), message.getFromUserId(), message.getToUserId(), message.getContent(), message.getCreatedAt());
		myMessage.setMe(true);
		return new ResponseEntity<>(myMessage, HttpStatus.OK);
	}
}
